package freespiritsocial.io.user.network

import android.annotation.SuppressLint
import android.os.Build
import com.google.gson.GsonBuilder
import freespiritsocial.io.user.BuildConfig
import me.hgj.jetpackmvvm.base.appContext
import me.hgj.jetpackmvvm.network.BaseNetworkApi
import me.hgj.jetpackmvvm.network.interceptor.logging.LogInterceptor
import okhttp3.Cache
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.io.File
import java.net.Socket
import java.security.SecureRandom
import java.security.cert.X509Certificate
import java.util.concurrent.TimeUnit
import javax.net.ssl.*

/**
 * 描述　: 网络请求构建器，继承BasenetworkApi 并实现setHttpClientBuilder/setRetrofitBuilder方法，
 * 在这里可以添加拦截器，设置构造器可以对Builder做任意操作
 */


//双重校验锁式-单例 封装NetApiService 方便直接快速调用简单的接口
val apiService: ApiService by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
    NetworkApi.INSTANCE.getApi(ApiService::class.java,BuildConfig.APP_URL)
}
val trustManager = object: X509TrustManager {
    override fun checkClientTrusted(chain: Array<out X509Certificate>?,authType: String?) {
    }

    override fun checkServerTrusted(chain: Array<out X509Certificate>?,authType: String?) {
    }

    override fun getAcceptedIssuers(): Array<X509Certificate> {
        return arrayOf()
    }

}
val apiFileService: ApiService by lazy {
    val builder = OkHttpClient.Builder()
        .apply {
            connectTimeout(30,TimeUnit.SECONDS)
            readTimeout(30,TimeUnit.SECONDS)
            writeTimeout(30,TimeUnit.SECONDS)
            // 日志拦截器
            if (BuildConfig.DEBUG) {
                addInterceptor(LogInterceptor())
            }
            try {

                val sslContext = SSLContext.getInstance("TLS")
                sslContext.init(null,arrayOf(trustManager),SecureRandom())
                sslSocketFactory(sslContext.socketFactory,trustManager)
                hostnameVerifier { _,_ ->
                    true
                }
            } catch (ex: Exception) {
                ex.printStackTrace()
            }
        }
    val retrofitBuilder = Retrofit.Builder()
        .baseUrl(BuildConfig.APP_URL)
        .addConverterFactory(GsonConverterFactory.create(GsonBuilder().create()))
        .client(builder.build())
        .build()
    retrofitBuilder.create(ApiService::class.java)
}

class NetworkApi: BaseNetworkApi() {

    companion object {
        val INSTANCE: NetworkApi by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
            NetworkApi()
        }
    }

    /**
     * 实现重写父类的setHttpClientBuilder方法，
     * 在这里可以添加拦截器，可以对 OkHttpClient.Builder 做任意操作
     */
    override fun setHttpClientBuilder(builder: OkHttpClient.Builder): OkHttpClient.Builder {
        builder.apply {
            //设置缓存配置 缓存最大10M
            cache(Cache(File(appContext.cacheDir,"cxk_cache"),10 * 1024 * 1024))
            //添加Cookies自动持久化
//            cookieJar(cookieJar)
            //示例：添加公共heads 注意要设置在日志拦截器之前，不然Log中会不显示head信息
            addInterceptor(MyHeadInterceptor())
            //添加缓存拦截器 可传入缓存天数，不传默认7天
//            addInterceptor(CacheInterceptor())
            // 日志拦截器
            if (BuildConfig.DEBUG) {
                addInterceptor(LogInterceptor())
            }
            //超时时间 连接、读、写
            connectTimeout(30,TimeUnit.SECONDS)
            readTimeout(30,TimeUnit.SECONDS)
            writeTimeout(30,TimeUnit.SECONDS)
            /** 设置忽略证书校验 **/
            try {
                val sslContext = SSLContext.getInstance("TLS")
                sslContext.init(null,arrayOf(trustManager),SecureRandom())
                sslSocketFactory(sslContext.socketFactory,trustManager)
                hostnameVerifier { _,_ ->
                    true
                }
            } catch (ex: Exception) {
                ex.printStackTrace()
            }
        }
        return builder
    }

    /**
     * 实现重写父类的setRetrofitBuilder方法，
     * 在这里可以对Retrofit.Builder做任意操作，比如添加GSON解析器，protobuf等
     */
    override fun setRetrofitBuilder(builder: Retrofit.Builder): Retrofit.Builder {
        return builder.apply {
            addConverterFactory(GsonConverterFactory.create(GsonBuilder().create()))
        }
    }

    private fun getSSLSocketFactory(): SSLSocketFactory {
        val sslContext: SSLContext = SSLContext.getInstance("SSL")
        sslContext.init(null,getTrustManager(),SecureRandom())
        return sslContext.socketFactory
    }

    @SuppressLint("TrustAllX509TrustManager")
    private fun getTrustManager(): Array<TrustManager> {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            arrayOf(
                object: X509ExtendedTrustManager() {
                    override fun checkClientTrusted(
                        chain: Array<out X509Certificate>?,
                        authType: String?,
                        socket: Socket?
                    ) {
                    }

                    override fun checkClientTrusted(
                        chain: Array<out X509Certificate>?,
                        authType: String?,
                        engine: SSLEngine?
                    ) {
                    }

                    override fun checkClientTrusted(
                        chain: Array<out X509Certificate>?,
                        authType: String?
                    ) {
                    }

                    override fun checkServerTrusted(
                        chain: Array<out X509Certificate>?,
                        authType: String?,
                        socket: Socket?
                    ) {
                    }

                    override fun checkServerTrusted(
                        chain: Array<out X509Certificate>?,
                        authType: String?,
                        engine: SSLEngine?
                    ) {
                    }

                    override fun checkServerTrusted(
                        chain: Array<out X509Certificate>?,
                        authType: String?
                    ) {
                    }

                    override fun getAcceptedIssuers(): Array<X509Certificate?> {
                        return arrayOfNulls(0)
                    }
                }
            )
        } else {
            arrayOf(
                object: X509TrustManager {
                    override fun checkClientTrusted(
                        chain: Array<out X509Certificate>?,
                        authType: String?
                    ) {
                    }

                    override fun checkServerTrusted(
                        chain: Array<out X509Certificate>?,
                        authType: String?
                    ) {
                    }

                    override fun getAcceptedIssuers(): Array<X509Certificate?> {
                        return arrayOfNulls(0)
                    }
                }
            )
        }
    }
}

@SuppressLint("TrustAllX509TrustManager")
class CreateSSLFactory {

    fun getSSLSocketFactory(): SSLSocketFactory {
        val sslContext: SSLContext = SSLContext.getInstance("SSL")
        sslContext.init(null,getTrustManager(),SecureRandom())
        return sslContext.socketFactory
    }

    private fun getTrustManager(): Array<TrustManager> {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            arrayOf(
                object: X509ExtendedTrustManager() {
                    override fun checkClientTrusted(
                        chain: Array<out X509Certificate>?,
                        authType: String?,
                        socket: Socket?
                    ) {
                    }

                    override fun checkClientTrusted(
                        chain: Array<out X509Certificate>?,
                        authType: String?,
                        engine: SSLEngine?
                    ) {
                    }

                    override fun checkClientTrusted(
                        chain: Array<out X509Certificate>?,
                        authType: String?
                    ) {
                    }

                    override fun checkServerTrusted(
                        chain: Array<out X509Certificate>?,
                        authType: String?,
                        socket: Socket?
                    ) {
                    }

                    override fun checkServerTrusted(
                        chain: Array<out X509Certificate>?,
                        authType: String?,
                        engine: SSLEngine?
                    ) {
                    }

                    override fun checkServerTrusted(
                        chain: Array<out X509Certificate>?,
                        authType: String?
                    ) {
                    }

                    override fun getAcceptedIssuers(): Array<X509Certificate?> {
                        return arrayOfNulls(0)
                    }
                }
            )
        } else {
            arrayOf(
                object: X509TrustManager {
                    override fun checkClientTrusted(
                        chain: Array<out X509Certificate>?,
                        authType: String?
                    ) {
                    }

                    override fun checkServerTrusted(
                        chain: Array<out X509Certificate>?,
                        authType: String?
                    ) {
                    }

                    override fun getAcceptedIssuers(): Array<X509Certificate?> {
                        return arrayOfNulls(0)
                    }
                }
            )
        }
    }
}



